home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 11 / Cream of the Crop 11-1.iso / compress / gnucpio.zip / IDCACHE.C < prev    next >
C/C++ Source or Header  |  1995-06-24  |  5KB  |  211 lines

  1. /* idcache.c -- map user and group IDs, cached for speed
  2.    Copyright (C) 1985, 1988, 1989, 1990 Free Software Foundation, Inc.
  3.  
  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 2, or (at your option)
  7.    any later version.
  8.  
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; if not, write to the Free Software
  16.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  17.  
  18. #ifdef HAVE_CONFIG_H
  19. #include <config.h>
  20. #endif
  21.  
  22. #include <stdio.h>
  23. #include <sys/types.h>
  24. #include <pwd.h>
  25. #include <grp.h>
  26.  
  27. #if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
  28. #include <string.h>
  29. #else
  30. #include <strings.h>
  31. #endif
  32.  
  33. #ifdef HAVE_UNISTD_H
  34. #include <unistd.h>
  35. #endif
  36. #ifndef _POSIX_VERSION
  37. struct passwd *getpwuid ();
  38. struct passwd *getpwnam ();
  39. struct group *getgrgid ();
  40. struct group *getgrnam ();
  41. #endif
  42.  
  43. char *xmalloc ();
  44. char *xstrdup ();
  45.  
  46. struct userid
  47. {
  48.   union
  49.     {
  50.       uid_t u;
  51.       gid_t g;
  52.     } id;
  53.   char *name;
  54.   struct userid *next;
  55. };
  56.  
  57. static struct userid *user_alist;
  58.  
  59. /* The members of this list have names not in the local passwd file.  */
  60. static struct userid *nouser_alist;
  61.  
  62. /* Translate UID to a login name or a stringified number,
  63.    with cache.  */
  64.  
  65. char *
  66. getuser (uid)
  67.      uid_t uid;
  68. {
  69.   register struct userid *tail;
  70.   struct passwd *pwent;
  71.   char usernum_string[20];
  72.  
  73.   for (tail = user_alist; tail; tail = tail->next)
  74.     if (tail->id.u == uid)
  75.       return tail->name;
  76.  
  77.   pwent = getpwuid (uid);
  78.   tail = (struct userid *) xmalloc (sizeof (struct userid));
  79.   tail->id.u = uid;
  80.   if (pwent == 0)
  81.     {
  82.       sprintf (usernum_string, "%u", (unsigned) uid);
  83.       tail->name = xstrdup (usernum_string);
  84.     }
  85.   else
  86.     tail->name = xstrdup (pwent->pw_name);
  87.  
  88.   /* Add to the head of the list, so most recently used is first.  */
  89.   tail->next = user_alist;
  90.   user_alist = tail;
  91.   return tail->name;
  92. }
  93.  
  94. /* Translate USER to a UID, with cache.
  95.    Return NULL if there is no such user.
  96.    (We also cache which user names have no passwd entry,
  97.    so we don't keep looking them up.)  */
  98.  
  99. uid_t *
  100. getuidbyname (user)
  101.      char *user;
  102. {
  103.   register struct userid *tail;
  104.   struct passwd *pwent;
  105.  
  106.   for (tail = user_alist; tail; tail = tail->next)
  107.     /* Avoid a function call for the most common case.  */
  108.     if (*tail->name == *user && !strcmp (tail->name, user))
  109.       return &tail->id.u;
  110.  
  111.   for (tail = nouser_alist; tail; tail = tail->next)
  112.     /* Avoid a function call for the most common case.  */
  113.     if (*tail->name == *user && !strcmp (tail->name, user))
  114.       return 0;
  115.  
  116.   pwent = getpwnam (user);
  117.  
  118.   tail = (struct userid *) xmalloc (sizeof (struct userid));
  119.   tail->name = xstrdup (user);
  120.  
  121.   /* Add to the head of the list, so most recently used is first.  */
  122.   if (pwent)
  123.     {
  124.       tail->id.u = pwent->pw_uid;
  125.       tail->next = user_alist;
  126.       user_alist = tail;
  127.       return &tail->id.u;
  128.     }
  129.  
  130.   tail->next = nouser_alist;
  131.   nouser_alist = tail;
  132.   return 0;
  133. }
  134.  
  135. /* Use the same struct as for userids.  */
  136. static struct userid *group_alist;
  137. static struct userid *nogroup_alist;
  138.  
  139. /* Translate GID to a group name or a stringified number,
  140.    with cache.  */
  141.  
  142. char *
  143. getgroup (gid)
  144.      gid_t gid;
  145. {
  146.   register struct userid *tail;
  147.   struct group *grent;
  148.   char groupnum_string[20];
  149.  
  150.   for (tail = group_alist; tail; tail = tail->next)
  151.     if (tail->id.g == gid)
  152.       return tail->name;
  153.  
  154.   grent = getgrgid (gid);
  155.   tail = (struct userid *) xmalloc (sizeof (struct userid));
  156.   tail->id.g = gid;
  157.   if (grent == 0)
  158.     {
  159.       sprintf (groupnum_string, "%u", (unsigned int) gid);
  160.       tail->name = xstrdup (groupnum_string);
  161.     }
  162.   else
  163.     tail->name = xstrdup (grent->gr_name);
  164.  
  165.   /* Add to the head of the list, so most recently used is first.  */
  166.   tail->next = group_alist;
  167.   group_alist = tail;
  168.   return tail->name;
  169. }
  170.  
  171. /* Translate GROUP to a UID, with cache.
  172.    Return NULL if there is no such group.
  173.    (We also cache which group names have no group entry,
  174.    so we don't keep looking them up.)  */
  175.  
  176. gid_t *
  177. getgidbyname (group)
  178.      char *group;
  179. {
  180.   register struct userid *tail;
  181.   struct group *grent;
  182.  
  183.   for (tail = group_alist; tail; tail = tail->next)
  184.     /* Avoid a function call for the most common case.  */
  185.     if (*tail->name == *group && !strcmp (tail->name, group))
  186.       return &tail->id.g;
  187.  
  188.   for (tail = nogroup_alist; tail; tail = tail->next)
  189.     /* Avoid a function call for the most common case.  */
  190.     if (*tail->name == *group && !strcmp (tail->name, group))
  191.       return 0;
  192.  
  193.   grent = getgrnam (group);
  194.  
  195.   tail = (struct userid *) xmalloc (sizeof (struct userid));
  196.   tail->name = xstrdup (group);
  197.  
  198.   /* Add to the head of the list, so most recently used is first.  */
  199.   if (grent)
  200.     {
  201.       tail->id.g = grent->gr_gid;
  202.       tail->next = group_alist;
  203.       group_alist = tail;
  204.       return &tail->id.g;
  205.     }
  206.  
  207.   tail->next = nogroup_alist;
  208.   nogroup_alist = tail;
  209.   return 0;
  210. }
  211.